package org.luxor.commons.sms.client.qcloud;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import org.luxor.commons.core.utils.Jackson2Utils;
import org.luxor.commons.core.utils.StrKit;
import org.luxor.commons.sms.client.AbstractSmsClient;
import org.luxor.commons.sms.config.properies.QcloudProperties;
import org.luxor.commons.sms.entity.PhoneNumber;
import org.luxor.commons.sms.exception.SmsServiceExection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * 腾讯云 短信服务
 *
 * @author Mr.yan @date 2020/2/8
 */
public class QcloudSmsClient extends AbstractSmsClient {
    private static final Logger logger = LoggerFactory.getLogger(QcloudSmsClient.class);
    private static final String SEND_SUCCESS = "Ok";
    /**
     * 腾讯云 全局配置项
     */
    private final QcloudProperties properties;

    private SmsClient client;

    public QcloudSmsClient(QcloudProperties properties) {
        this.properties = properties;
        if (this.isEnabled()) {
            this.init();
        }
    }

    private void init() {
        logger.info("Initialization Qcloud open ( Running Qcloud Connector)");
        try {
            Credential cred = new Credential(properties.getSecretId(), properties.getSecretKey());

            ClientProfile clientProfile = new ClientProfile();
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint(properties.getEndPoint());
            clientProfile.setHttpProfile(httpProfile);

            client = new SmsClient(cred, "", clientProfile);
            logger.info("Initialize Qcloud Connector Success,bye");
        } catch (Throwable e) {
            logger.error("Initialize Qcloud Connector Failure!", e);
            throw e;
        }
    }

    @Override
    public boolean isEnabled() {
        return properties.isEnabled();
    }

    @Override
    public void sendMessage(Set<PhoneNumber> phoneNumbers, String templateId, Map<String, String> context, String sender) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 腾讯云短信发送功能");
            throw new SmsServiceExection("[未开启]  腾讯云短信发发送功能");
        }
        if (phoneNumbers == null || phoneNumbers.isEmpty()) {
            return;
        }
        int index = 0;
        String[] phoneNumberSet = new String[phoneNumbers.size()];
        for (PhoneNumber phoneNumber : phoneNumbers) {
            phoneNumberSet[index] = phoneNumber.toString();
            index++;
        }
        try {
            logger.debug("腾讯云短信发送开始... 接收手机号:{} / 短信模板ID:{} / 发送人:{}", phoneNumbers, templateId, sender);
            SendSmsRequest req = new SendSmsRequest();
            req.setSmsSdkAppid(properties.getAppId());
            req.setPhoneNumberSet(phoneNumberSet);
            req.setTemplateID(templateId);
            req.setSign(properties.getSign());
            if (context != null) {
                String[] templateParamSet = new String[context.size()];
                for (int i = 1; i <= templateParamSet.length; i++) {
                    templateParamSet[i - 1] = context.getOrDefault(String.valueOf(i), StrKit.EMPTY);
                }
                req.setTemplateParamSet(templateParamSet);
            }
            if (StringUtils.hasText(sender)) {
                req.setSessionContext(sender);
            }
            // 批量发送短信
            SendSmsResponse response = client.SendSms(req);
            // 检查响应结果中发送失败的记录
            checkSendException(response);

            logger.debug("腾讯云短信发送完成, server requestId :{}", response.getRequestId());
        } catch (SmsServiceExection smsServiceExection) {
            throw smsServiceExection;
        } catch (Exception e) {
            logger.error("腾讯云短信发送失败，请核对腾讯云配置信息", e);
            throw new SmsServiceExection("腾讯云短信发送失败，请核对腾讯云配置信息", e);
        }
    }

    private void checkSendException(SendSmsResponse response) {
        if (response == null || response.getSendStatusSet() == null) {
            throw new SmsServiceExection("腾讯云短信发送失败，服务器没有响应");
        }
        List<SendStatus> errorSends = new ArrayList<>();
        SendStatus[] sendStatus = response.getSendStatusSet();
        for (SendStatus status : sendStatus) {
            if (!SEND_SUCCESS.equalsIgnoreCase(status.getCode())) {
                errorSends.add(status);
            }
        }
        if (!errorSends.isEmpty()) {
            logger.error("腾讯云短信发送失败, 详情反馈:{}", Jackson2Utils.toJsonPretty(response));
            throw new SmsServiceExection(-1, "腾讯云短信发送失败", Jackson2Utils.toJsonPretty(errorSends));
        }
    }
}
